package com.github.catvod.spider;

import android.content.Context;
import com.github.catvod.bean.Class;
import com.github.catvod.bean.Result;
import com.github.catvod.bean.Vod;
import com.github.catvod.crawler.Spider;
import com.github.catvod.net.OkHttp;
import org.json.JSONArray;
import org.json.JSONObject;

import java.net.URLEncoder;
import java.util.*;


/**
 * @author 文又七
 * 360
 */
public class SP360 extends Spider {

    private final String userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:102.0) Gecko/20100101 Firefox/102.0";

    private static String jxurl;

    /**
     * 爬虫代码初始化
     *
     * @param context 上下文对象
     * @param extend  配置文件的 ext 参数
     */
    @Override
    public void init(Context context, String extend) throws Exception {
        super.init(context, extend);
        // 域名经常性发生变化，通过外部配置文件传入，可以方便修改
        if (extend.endsWith("/")) {
            extend = extend.substring(0, extend.lastIndexOf("/"));
        }
        jxurl = extend;
    }


    @Override
    public String homeContent(boolean filter) {
        List<Class> classes = new ArrayList<>();
        classes.add(new Class("1", "电影"));
        classes.add(new Class("2", "电视剧"));
        classes.add(new Class("3", "综艺"));
        classes.add(new Class("4", "动漫"));
        return Result.string(classes, new ArrayList<>());
    }

    @Override
    public String categoryContent(String tid, String pg, boolean filter, HashMap<String, String> extend) throws Exception {

        HashMap<String, String> ext = new HashMap<>();
        if (extend != null && extend.size() > 0) {
            ext.putAll(extend);
        }
        String by = ext.get("by") == null ? "ranklatest" : ext.get("by");
        String classType = ext.get("class") == null ? "" : ext.get("class");
        String year = ext.get("year") == null ? "" : ext.get("year");
        String area = ext.get("area") == null ? "" : ext.get("area");
        String actor = ext.get("actor") == null ? "" : ext.get("actor");
        StringBuilder sb = new StringBuilder()
                .append("rank=").append(by)
                .append("&cat=").append(URLEncoder.encode(classType))
                .append("&year=").append(year)
                .append("&area=").append(URLEncoder.encode(area))
                .append("&act=").append(URLEncoder.encode(actor));

        String detailClassId = "";
        String categoryClassId = "";
        switch (tid) {
            case "1": // 电影
                categoryClassId = "dianying";
                detailClassId = "m";
                break;
            case "2": // 电视剧
                categoryClassId = "dianshi";
                detailClassId = "tv";
                break;
            case "3": // 综艺
                categoryClassId = "zongyi";
                detailClassId = "va";
                break;
            case "4": // 动漫
                categoryClassId = "dongman";
                detailClassId = "ct";
        }

        String cateUrl = "https://api.web.360kan.com/v1/filter/list?catid=" + tid + "&" + sb + "&size=35&callback=";
        String referer = "https://www.360kan.com/" + categoryClassId + "/list?" + sb;
        if (!pg.equals("1")) {
            // 第二页开始
            cateUrl = "https://api.web.360kan.com/v1/filter/list?catid=" + tid + "&" + sb + "&size=35&pageno=" + pg + "&callback=";
            referer = "https://www.360kan.com/" + categoryClassId + "/list?" + sb + "&pageno=" + pg;
        }

        Map<String, String> H = new HashMap<>();
        H.put("User-Agent", userAgent);
        H.put("referer", referer);
        String content = OkHttp.string(cateUrl, H);

        List<Vod> list = new ArrayList<>();
        JSONArray items = new JSONObject(content).optJSONObject("data").optJSONArray("movies");
        for (int i = 0; i < items.length(); i++) {
            JSONObject item = items.optJSONObject(i);
            String id = item.optString("id");
            String vid = "https://api.web.360kan.com/v1/detail?cat=" + tid + "&id=" + id + "&callback=";
            String detailReferer = "https://www.360kan.com/" + detailClassId + "/" + id + ".html";
            JSONObject detailObj = new JSONObject().put("detailUrl", vid).put("detailReferer", detailReferer);
            String name = item.optString("title");
            String pic = "http:" + item.optString("cdncover");
            String remark = "";
            list.add(new Vod(detailObj.toString(), name, pic, remark));

        }

        int total = new JSONObject(content).optJSONObject("data").optInt("total");
        int count = total % 35 == 0 ? (total / 35) : (total / 35 + 1);
        return Result.get().vod(list).page(Integer.parseInt(pg), count, 35, total).string();


    }


    @Override
    public String detailContent(List<String> ids) throws Exception {
        JSONObject detailObj = new JSONObject(ids.get(0));
        String detailUrl = detailObj.optString("detailUrl");
        String detailReferer = detailObj.optString("detailReferer");
        Map<String, String> H = new HashMap<>();
        H.put("User-Agent", userAgent);
        H.put("referer", detailReferer);
        String detailResult = OkHttp.string(detailUrl, H);

        JSONObject data = new JSONObject(detailResult).optJSONObject("data");

        // 影片标题
        String name = data.optString("title");

        boolean isTV = data.has("allepidetail"); // 电视或者动漫的标志
        boolean isVarietyShow = data.has("defaultepisode"); // 综艺类型标志

        List<String> playFrom = new ArrayList<>();
        List<String> playUrl = new ArrayList<>();
        JSONObject playLinksDetail = data.optJSONObject("playlinksdetail");
        JSONArray playLinkSites = data.optJSONArray("playlink_sites");
        String subStr = detailUrl.substring(0, detailUrl.indexOf("&callback="));
        if (isTV) {
            // 进入这里说明是电视剧或者动漫
            // 有很多集
            // 需要针对一些还没有查询出来的数据做查询，获取其他站源的数据
            for (int i = 0; i < playLinkSites.length(); i++) {
                String site = String.valueOf(playLinkSites.get(i));
                String upInfoURL = subStr + "&site=" + site + "&callback=";
                JSONObject allUpInfo = new JSONObject(OkHttp.string(upInfoURL, H))
                        .optJSONObject("data")
                        .optJSONObject("allupinfo");
                int upInfo = 0;
                if (allUpInfo.has(site)) {
                    upInfo = Integer.parseInt(String.valueOf(allUpInfo.get(site)));
                }
                List<String> vodItems = new ArrayList<>();
                for (int j = 0; j < upInfo; j += 200) {
                    int end = j + 200;
                    if (end > upInfo) {
                        end = upInfo;
                    }
                    int start = j + 1;
                    String episodeDetailURL = subStr + "&start=" + start + "&end=" + end + "&site=" + site + "&callback=";
                    JSONArray episodes2 = new JSONObject(OkHttp.string(episodeDetailURL, H))
                            .optJSONObject("data")
                            .optJSONObject("allepidetail")
                            .optJSONArray(site);
                    if (episodes2 == null) continue;
                    for (int k = 0; k < episodes2.length(); k++) {
                        JSONObject item = episodes2.optJSONObject(k);
                        String episodeName = "第" + item.optString("playlink_num") + "集";
                        String episodeURL = item.optString("url");
                        vodItems.add(episodeName + "$" + episodeURL);
                    }
                }
                if (vodItems.size() > 0) {
                    playFrom.add(site);
                    playUrl.add(String.join("#", vodItems));
                }
            }
        } else if (isVarietyShow) {
            // 进入这里说明是综艺类型
            // 遍历 playLinkSites 发起请求获取
            for (int i = 0; i < playLinkSites.length(); i++) {
                String site = String.valueOf(playLinkSites.get(i));
                if (data.has("tag")) {
                    // 有 tag 标签 ，说明有按年份区分该综艺节目
                    Iterator<String> keys = data.optJSONObject("tag").keys();
                    List<String> vodItems = new ArrayList<>();
                    while (keys.hasNext()) {
                        String year = keys.next();
                        String episodeDetailURL = subStr + "&site=" + site + "&year=" + year + "&callback=";
                        JSONArray episodes = new JSONObject(OkHttp.string(episodeDetailURL, H))
                                .optJSONObject("data")
                                .optJSONArray("defaultepisode");
                        if (episodes == null) continue;
                        for (int j = 0; j < episodes.length(); j++) {
                            JSONObject item = episodes.optJSONObject(j);
                            String episodeName = item.optString("period") + " " + item.optString("name");
                            String episodeURL = item.optString("url");
                            vodItems.add(episodeName + "$" + episodeURL);
                        }
                    }
                    if (vodItems.size() > 0) {
                        playFrom.add(site);
                        playUrl.add(String.join("#", vodItems));
                    }
                }
            }
        } else {
            // 电影的默认处理
            for (int i = 0; i < playLinkSites.length(); i++) {
                String site = String.valueOf(playLinkSites.get(i));
                // if (site.contains("douyin") || site.contains("xigua")) continue;
                String defaultUrl = playLinksDetail.optJSONObject(site).optString("default_url");
                List<String> vodItems = new ArrayList<>();
                vodItems.add(name + "$" + defaultUrl);
                playFrom.add(site);
                playUrl.add(String.join("#", vodItems));
            }
        }
        // 图片
        String pic = data.optString("cdncover");
        String typeName = getCorrectString(data.optJSONArray("moviecategory"));
        String year = data.optString("pubdate");
        String area = getCorrectString(data.optJSONArray("area"));
        String actor = getCorrectString(data.optJSONArray("actor"));
        String director = getCorrectString(data.optJSONArray("director"));
        String description = data.optString("description");
        Vod vod = new Vod();
        vod.setVodId(ids.get(0));
        vod.setVodPic(pic);
        vod.setTypeName(typeName);
        vod.setVodActor(actor);
        vod.setVodName(name);
        vod.setVodArea(area);
        vod.setVodDirector(director);
        vod.setVodContent(description);
        vod.setVodYear(year);
        vod.setVodPlayFrom(String.join("$$$", playFrom));
        vod.setVodPlayUrl(String.join("$$$", playUrl));
        return Result.string(vod);
    }

    private String getCorrectString(JSONArray jsonArray) {
        if (jsonArray != null) {
            return jsonArray.toString()
                    .replace("\"", "")
                    .replace("[", "")
                    .replace("]", "");
        }
        return "";
    }

    @Override
    public String searchContent(String key, boolean quick) throws Exception {
        Map<String, String> H = new HashMap<>();
        H.put("User-Agent", userAgent);

        String keyword = URLEncoder.encode(key);
        String searchURL = "https://api.so.360kan.com/index?force_v=1&kw=" + keyword + "&from=&pageno=1&v_ap=1&tab=all";
        String referer = "https://so.360kan.com/?kw=" + keyword;
        H.put("referer", referer);
        String searchResult = OkHttp.string(searchURL, H);
        JSONArray rows = new JSONObject(searchResult)
                .optJSONObject("data")
                .optJSONObject("longData")
                .optJSONArray("rows");
        List<Vod> list = new ArrayList<>();
        for (int i = 0; i < rows.length(); i++) {
            JSONObject item = rows.optJSONObject(i);
            String id = item.optString("en_id");
            String tid = item.optString("cat_id");
            String vid = "https://api.web.360kan.com/v1/detail?cat=" + tid + "&id=" + id + "&callback=";
            String detailReferer = item.optString("url");
            JSONObject detailObj = new JSONObject().put("detailUrl", vid).put("detailReferer", detailReferer);
            String name = item.optString("titleTxt");
            String pic = item.optString("cover");
            String remark = item.optString("cat_name");
            list.add(new Vod(detailObj.toString(), name, pic, remark));
        }
        return Result.string(list);
    }

    @Override
    public String playerContent(String flag, String id, List<String> vipFlags) {
        //远程嗅探，反爬
        String u = jxurl + "/t2?flag=" + flag + "&url=" + URLEncoder.encode(id);
        String urls = OkHttp.string(u);
        Map<String, String> header = new HashMap<>();
        header.put("user-agent", userAgent);
        return Result.get().url(urls).parse(0).header(header).string();
    }
}
